Skip to content

Conversation

@ceorourke
Copy link
Member

@ceorourke ceorourke commented Nov 20, 2025

Fixes adding and updating sentry app actions on a workflow and requires settings to be passed for a sentry app action if it has a UI component. If it has no component, settings does not need to be passed.

Adds support for a target_type of either sentry_app_id or sentry_app_installation_uuid until we can migrate the data to only have sentry_app_id.

Add tests for adding and updating sentry app actions.

Fixes https://sentry.sentry.io/issues/6980690322

@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Nov 20, 2025
@codecov
Copy link

codecov bot commented Nov 20, 2025

❌ 1 Tests Failed:

Tests completed Failed Passed Skipped
30056 1 30055 240
View the full list of 1 ❄️ flaky test(s)
tests.sentry.core.endpoints.test_organization_index.OrganizationsCreateTest::test_valid_slugs

Flake rate in main: 61.11% (Passed 7 times, Failed 11 times)

Stack Traces | 1.57s run time
#x1B[1m#x1B[.../core/endpoints/test_organization_index.py#x1B[0m:190: in test_valid_slugs
    response = self.get_success_response(name=input_slug, slug=input_slug)
#x1B[1m#x1B[.../sentry/testutils/cases.py#x1B[0m:628: in get_success_response
    assert_status_code(response, 200, 300)
#x1B[1m#x1B[.../sentry/testutils/asserts.py#x1B[0m:47: in assert_status_code
    assert minimum <= response.status_code < maximum, (
#x1B[1m#x1B[31mE   AssertionError: (500, b'{"detail":"Internal Error","errorId":null}')#x1B[0m
#x1B[1m#x1B[31mE   assert 500 < 300#x1B[0m
#x1B[1m#x1B[31mE    +  where 500 = <Response status_code=500, "application/json">.status_code#x1B[0m

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

Comment on lines +160 to +184
"sentryAppIdentifier": SentryAppIdentifier.SENTRY_APP_INSTALLATION_UUID,
"targetIdentifier": self.sentry_app_installation.uuid,
"targetType": ActionType.SENTRY_APP,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ameliahsu I was only able to get this test to pass if I used this data which differs from what was passed in https://sentry.sentry.io/issues/6980690322 which was

{
    "sentry_app_identifier":"'sentry_app_id'",
    "target_identifier":"'72013'",
    "target_type":"'sentry_app'"
}

Do you know if the data in the Sentry issue is what's expected to be passed all the time or only sometimes? I'm not sure when we pass one versus the other, but if we set sentryAppIdentifier to "sentry_app" instead of "sentry_app_installation" (SentryAppIdentifier.SENTRY_APP_INSTALLATION_UUID) we go down a slightly different code path and set sentryAppInstallationUuid to None (code here) which leads to a SentryAppInstallation.DoesNotExist error (here).

I truly don't know if this is a bug or how it's intended to work, but it doesn't currently work if you do not pass the installation data. I did verify that even an internal unpublished sentry app has an installation object, so maybe it's intended for us to always pass that data?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@GabeVillalobos might be able to help here, i believe some existing app actions use the sentry app UUID instead of the sentry app ID, which is why we have to specify sentry_app_identifier? but we would like for all newly created actions going forward to use sentry app ID. not sure if that's why we throw an error tho 😅

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Short answer here is that sentry_app_installation is some legacy data we need to migrate away from and the front end will be passing sentry_app_id for new actions. I updated the code to support both until we can run the migration so that old action with the uuid can be updated.

Comment on lines 246 to 249
if settings:
try:
# Only call creator for Sentry Apps with UI Components (settings) for actions
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I copied this logic from how we do it today - in project_rule_details.py and project_rules.py we call trigger_sentry_app_action_creators_for_issues (here) which skips over the validation if there is no UI component

except SentryAppInstallation.DoesNotExist:
return None

def get_installation_by_uuid(
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We only need this temporarily until we can migrate the action data to not have the installation uuid

)
else:
installations = app_service.get_many(
filter=dict(app_ids=[int(target_identifier)], organization_id=self.organization.id)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Unhandled ValueError when converting target identifier to int

When sentry_app_identifier is SENTRY_APP_ID, the code converts target_identifier to an integer without error handling. If a user passes a non-numeric string (like a UUID) as the target_identifier, this will raise an unhandled ValueError instead of returning a proper validation error, causing a 500 error rather than a user-friendly 400 validation error.

Fix in Cursor Fix in Web

@ceorourke ceorourke force-pushed the ceorourke/fix-sentry-app-actions branch from ea7ebbd to 0ef73d2 Compare November 26, 2025 18:01
)
else:
installations = app_service.get_many(
filter=dict(app_ids=[int(target_identifier)], organization_id=self.organization.id)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: target_identifier lacks numeric validation in schema, causing ValueError during int() conversion for non-numeric inputs.
Severity: CRITICAL | Confidence: High

🔍 Detailed Analysis

The target_identifier field lacks proper validation in the JSON schema, allowing non-numeric strings to pass when sentry_app_identifier is SENTRY_APP_ID. This leads to a ValueError when int(target_identifier) is called at action_validation.py:225, causing an unhandled exception and server crash.

💡 Suggested Fix

Add a pattern constraint like "pattern": "^\\d+$" to the target_identifier field in the JSON schema, or implement conditional validation based on sentry_app_identifier. Alternatively, wrap int(target_identifier) in a try-except block.

🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: src/sentry/notifications/notification_action/action_validation.py#L225

Potential issue: The `target_identifier` field lacks proper validation in the JSON
schema, allowing non-numeric strings to pass when `sentry_app_identifier` is
`SENTRY_APP_ID`. This leads to a `ValueError` when `int(target_identifier)` is called at
`action_validation.py:225`, causing an unhandled exception and server crash.

Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 3862959

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants